package com.example.touchdemo01.views;


import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;

/**
 * 可缩放、可拖拽图片的ImageView
 */

@SuppressLint("AppCompatCustomView")
public class ZoomableImageView extends ImageView {
    public static final String TAG = "ZoomableImageView";
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;
    private PointF start = new PointF();
    private PointF mid = new PointF();
    private float oldDist = 1f;//双指距离
    private float[] matrixValues = new float[9];
    private float maxScale = 3f;
    private float minScale = 1f;

    public ZoomableImageView(Context context) {
        super(context);
        init();
    }

    public ZoomableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ZoomableImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setScaleType(ScaleType.MATRIX);
        setClickable(true);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 与ZoomableView中的实现相同
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "--------onTouchEvent--------down");
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                Log.e(TAG, "--------onTouchEvent-------- pointer down");
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                break;

            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                } else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;

                        matrix.getValues(matrixValues);
                        float currentScale = matrixValues[Matrix.MSCALE_X];

                        if (scale * currentScale > maxScale) {
                            scale = maxScale / currentScale;
                        } else if (scale * currentScale < minScale) {
                            scale = minScale / currentScale;
                        }

                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                }
                break;
        }

        //setImageMatrix(matrix);
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 保存当前画布状态
        canvas.save();
        // 应用矩阵变换
        canvas.concat(matrix);
        // 调用父类的onDraw方法绘制内容
        super.onDraw(canvas);
        // 恢复画布状态
        canvas.restore();
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    // 设置最大缩放比例
    public void setMaxScale(float maxScale) {
        this.maxScale = maxScale;
    }

    // 设置最小缩放比例
    public void setMinScale(float minScale) {
        this.minScale = minScale;
    }
}